

#include "mrpcapplication.h"

#include <fstream>
#include <iostream>
#include <cstdlib>  // for exit
#include <getopt.h> // for getopt

MrpcApplication::Conf MrpcApplication::_conf;

MrpcApplication &MrpcApplication::getInstance()
{
    static MrpcApplication app;
    return app;
};

// 打印使用帮助
void printUsage(const std::string &programName)
{
    std::cerr << "使用方法: " << programName << " -i <配置文件路径>" << std::endl;
    std::cerr << "功能: 启动MRPC服务，通过配置文件指定服务参数" << std::endl;
    std::cerr << "选项:" << std::endl;
    std::cerr << "  -i <file>   指定配置文件路径（必填），文件格式为k=v，#开头为注释" << std::endl;
}

// 辅助函数：去除字符串首尾空格
std::string trim(const std::string &str)
{
    if (str.empty())
        return "";

    size_t start = str.find_first_not_of(" \t");
    size_t end = str.find_last_not_of(" \t");

    if (start == std::string::npos)
        return "";
    return str.substr(start, end - start + 1);
}

// 读取k=v格式的配置文件（支持#注释）
bool readKvFile(const std::string &filename)
{
    std::ifstream file(filename);
    if (!file.is_open())
    {
        std::cerr << "无法打开配置文件: " << filename << std::endl;
        return false;
    }

    std::string line;
    int lineNum = 0;

    while (std::getline(file, line))
    {
        lineNum++;
        // 处理注释
        size_t commentPos = line.find('#');
        if (commentPos != std::string::npos)
        {
            line = line.substr(0, commentPos);
        }

        // 去除首尾空格
        std::string trimmedLine = trim(line);
        if (trimmedLine.empty())
        {
            continue; // 跳过空行
        }

        // 查找等号
        size_t eqPos = trimmedLine.find('=');
        if (eqPos == std::string::npos || eqPos == 0)
        {
            std::cerr << "警告：配置文件第" << lineNum << "行格式错误，已跳过" << std::endl;
            continue;
        }

        // 分割键值对
        std::string key = trim(trimmedLine.substr(0, eqPos));
        std::string value = trim(trimmedLine.substr(eqPos + 1));

        if (key.empty())
        {
            std::cerr << "警告：配置文件第" << lineNum << "行键为空，已跳过" << std::endl;
            continue;
        }

        MrpcApplication::_conf[key] = value;
    }

    file.close();
    return true;
}

void MrpcApplication::init(int argc, char **argv)
{
    // 动态加载conf
    // 默认配置文件路径
    std::string configFile;

    // 解析命令行参数
    int c;
    while ((c = getopt(argc, argv, "i:")) != -1)
    {
        switch (c)
        {
        case 'i':
            // 保存用户指定的配置文件路径
            configFile = optarg;
            break;
        case '?':
            // 处理未知选项
            if (optopt == 'i')
            {
                std::cerr << "错误：选项 -" << (char)optopt << " 需要一个参数（配置文件路径）" << std::endl;
            }
            else
            {
                std::cerr << "错误：未知选项 -" << (char)optopt << std::endl;
            }
            printUsage(argv[0]);
            exit(EXIT_FAILURE);
        default:
            printUsage(argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    // 检查是否提供了配置文件
    if (configFile.empty())
    {
        std::cerr << "错误：必须通过 -i 选项指定配置文件" << std::endl;
        printUsage(argv[0]);
        exit(EXIT_FAILURE);
    }

    // 读取并解析配置文件到unordered_map
    if (!readKvFile(configFile))
    { // 假设m_config是类内的unordered_map成员
        std::cerr << "错误：配置文件加载失败 - " << configFile << std::endl;
        exit(EXIT_FAILURE);
    }

    std::cout << "配置文件加载成功：" << configFile << std::endl;
}

MrpcApplication::MrpcApplication()
{
}
MrpcApplication::~MrpcApplication()
{
}
